#include "rollback_file_command.h"
#include "service/backend_service.h"
#include "../database/database_manager.h"
#include "command_executor.h"
#include <QDebug>
#include <QUrl>
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonParseError>

RollbackFileCommand::RollbackFileCommand(QObject *parent)
    : BaseCommand(parent)
    , m_commandExecutor(nullptr)
    , m_pendingFileId("")
{
}

RollbackFileCommand::~RollbackFileCommand()
{
}

void RollbackFileCommand::setNetworkAccessManager(QNetworkAccessManager *networkManager)
{
    // 如果之前已经设置了 networkManager，先断开旧的连接
    if (m_networkManager) {
        disconnect(m_networkManager, &QNetworkAccessManager::finished,
                   this, &RollbackFileCommand::handleRollbackFileResponse);
    }
    
    BaseCommand::setNetworkAccessManager(networkManager);
    
    // 连接网络请求完成信号
    if (m_networkManager) {
        connect(m_networkManager, &QNetworkAccessManager::finished,
                this, &RollbackFileCommand::handleRollbackFileResponse);
    }
}

void RollbackFileCommand::setCommandExecutor(CommandExecutor *commandExecutor)
{
    m_commandExecutor = commandExecutor;
}

bool RollbackFileCommand::execute(const QString &fileId)
{
    if (!isValid()) {
        qDebug() << "RollbackFileCommand: BackendService 或 QNetworkAccessManager 未设置";
        emit rollbackFileCompleted(-1, "BackendService 或 QNetworkAccessManager 未设置");
        return false;
    }
    
    if (fileId.isEmpty()) {
        qDebug() << "RollbackFileCommand: 文件ID为空";
        emit rollbackFileCompleted(-1, "文件ID为空");
        return false;
    }
    
    // 检查是否有accessToken，如果没有则先获取
    if (!ensureAccessToken()) {
        // 如果没有选中的公司ID，无法获取accessToken
        if (!m_backendService || m_backendService->loadSelectedCompanyId().isEmpty()) {
            qDebug() << "RollbackFileCommand: 没有选中的公司ID，无法获取accessToken";
            emit rollbackFileCompleted(-1, "没有选中的公司ID，无法获取accessToken");
            return false;
        }
        // 正在获取 token，保存待处理的文件ID
        m_pendingFileId = fileId;
        return true; // 返回true表示已发起获取token的请求
    }
    
    // 获取 accessToken
    QString accessToken = CommandExecutor::getAccessToken();
    
    // 获取 baseUrl
    QString baseUrl = getBaseUrl();
    
    // 构建请求URL
    QString url = buildRequestUrl(baseUrl, fileId);
    
    qDebug() << "RollbackFileCommand: 发送回撤文件请求到:" << url;
    qDebug() << "RollbackFileCommand: 文件ID:" << fileId;
    
    // 创建网络请求
    QNetworkRequest request;
    request.setUrl(QUrl(url));
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    
    // 添加token到请求头
    addTokenToRequest(request, accessToken);
    
    // 发送GET请求
    QNetworkReply *reply = m_networkManager->get(request);
    qDebug() << "RollbackFileCommand: 发送回撤文件请求，reply对象:" << reply;
    
    // 设置用户数据，用于识别请求类型
    reply->setProperty("requestType", "rollbackFile");
    
    // 保存文件ID到reply属性中
    reply->setProperty("fileId", fileId);
    
    return true;
}

void RollbackFileCommand::handleRollbackFileResponse(QNetworkReply *reply)
{
    // 检查对象是否仍然有效（可能在信号排队期间被销毁）
    if (!isValid()) {
        qDebug() << "RollbackFileCommand: 对象已被销毁，忽略响应";
        if (reply) {
            reply->deleteLater();
        }
        return;
    }
    
    if (!reply) {
        qDebug() << "RollbackFileCommand: 回撤文件响应为空";
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit rollbackFileCompleted(-1, "回撤响应为空");
        }
        return;
    }
    
    QString requestType = reply->property("requestType").toString();
    if (requestType != "rollbackFile") {
        // 不是回撤文件请求，忽略
        reply->deleteLater();
        return;
    }
    
    qDebug() << "RollbackFileCommand: 处理回撤文件响应，错误:" << reply->error();
    
    if (reply->error() == QNetworkReply::NoError) {
        // 获取文件信息成功
        QByteArray data = reply->readAll();
        qDebug() << "RollbackFileCommand: 获取文件信息成功，数据大小:" << data.size() << "字节";
        
        // 解析JSON响应
        QJsonParseError parseError;
        QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
        
        // 再次检查对象是否仍然有效
        if (!isValid()) {
            qDebug() << "RollbackFileCommand: 对象已被销毁，忽略响应解析";
            reply->deleteLater();
            return;
        }
        
        if (parseError.error != QJsonParseError::NoError) {
            qDebug() << "RollbackFileCommand: 回撤文件JSON解析错误:" << parseError.errorString();
            // 只有在对象仍然有效时才发送信号
            if (isValid()) {
                emit rollbackFileCompleted(-1, "JSON解析失败: " + parseError.errorString());
            }
            reply->deleteLater();
            return;
        }
        
        if (!doc.isObject()) {
            qDebug() << "RollbackFileCommand: 回撤文件响应不是有效的JSON对象";
            // 只有在对象仍然有效时才发送信号
            if (isValid()) {
                emit rollbackFileCompleted(-1, "响应格式错误");
            }
            reply->deleteLater();
            return;
        }
        
        // 最后一次检查对象是否仍然有效
        if (!isValid()) {
            qDebug() << "RollbackFileCommand: 对象已被销毁，忽略响应解析";
            reply->deleteLater();
            return;
        }
        
        QJsonObject response = doc.object();
        // 从reply属性中获取文件ID
        QString fileId = reply->property("fileId").toString();
        
        parseRollbackFileResponse(response, fileId);
    } else {
        qDebug() << "RollbackFileCommand: 回撤文件失败:" << reply->errorString();
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit rollbackFileCompleted(reply->error(), "回撤失败: " + reply->errorString());
        }
    }
    
    reply->deleteLater();
}

void RollbackFileCommand::parseRollbackFileResponse(const QJsonObject &response, const QString &fileId)
{
    // 检查对象是否仍然有效
    if (!isValid()) {
        qDebug() << "RollbackFileCommand: 对象已被销毁，忽略响应解析";
        return;
    }
    
    int errcode = response["errcode"].toInt();
    QString errmsg = response["errmsg"].toString();
    
    if (errcode == 0) {
        // 成功获取文件信息
        QJsonObject fileData = response["data"].toObject();
        qDebug() << "RollbackFileCommand: 获取文件信息成功:" << errmsg;
        qDebug() << "RollbackFileCommand: 文件信息:" << fileData;
        
        // 更新数据库中的文件信息
        if (m_databaseManager) {
            // 更新数据库中的文件信息
            bool updateSuccess = m_databaseManager->updateFileFromJson(fileData);
            if (updateSuccess) {
                qDebug() << "RollbackFileCommand: 数据库文件信息更新成功";
                
                // 获取文件URL并重新下载
                QString fileUrl = fileData["url"].toString();
                // 使用传入的文件ID，如果没有，尝试从fileData中获取
                QString actualFileId = fileId;
                if (actualFileId.isEmpty()) {
                    actualFileId = fileData["id"].toString();
                }
                
                if (!fileUrl.isEmpty()) {
                    qDebug() << "RollbackFileCommand: 开始重新下载文件，URL:" << fileUrl << "文件ID:" << actualFileId;
                    if (!actualFileId.isEmpty()) {
                        // 获取文件名（从fileData或数据库中）
                        QString fileName = fileData["name"].toString();
                        if (fileName.isEmpty() && m_databaseManager) {
                            KmsFile kmsFile = m_databaseManager->queryFileById(actualFileId);
                            fileName = kmsFile.name;
                        }
                        if (m_commandExecutor) {
                            m_commandExecutor->executeDownloadFile(fileUrl, fileName, actualFileId);
                        } else {
                            qDebug() << "RollbackFileCommand: CommandExecutor 未设置，无法执行下载文件命令";
                            // 只有在对象仍然有效时才发送信号
                            if (isValid()) {
                                emit rollbackFileCompleted(-1, "CommandExecutor 未设置");
                            }
                            return;
                        }
                        // 只有在对象仍然有效时才发送信号
                        if (isValid()) {
                            emit rollbackFileCompleted(0, "文件信息更新成功，开始重新下载");
                        }
                    } else {
                        // 如果没有文件ID，只传递URL（不推荐，但为了兼容性保留）
                        qDebug() << "RollbackFileCommand: 警告：没有文件ID，使用URL下载";
                        if (m_commandExecutor) {
                            m_commandExecutor->executeDownloadFile(fileUrl, "", "");
                        } else {
                            qDebug() << "RollbackFileCommand: CommandExecutor 未设置，无法执行下载文件命令";
                            // 只有在对象仍然有效时才发送信号
                            if (isValid()) {
                                emit rollbackFileCompleted(-1, "CommandExecutor 未设置");
                            }
                            return;
                        }
                        // 只有在对象仍然有效时才发送信号
                        if (isValid()) {
                            emit rollbackFileCompleted(0, "文件信息更新成功，开始重新下载");
                        }
                    }
                } else {
                    qDebug() << "RollbackFileCommand: 文件信息中没有URL字段";
                    // 只有在对象仍然有效时才发送信号
                    if (isValid()) {
                        emit rollbackFileCompleted(-1, "文件信息中没有URL字段");
                    }
                }
            } else {
                qDebug() << "RollbackFileCommand: 数据库文件信息更新失败";
                // 只有在对象仍然有效时才发送信号
                if (isValid()) {
                    emit rollbackFileCompleted(-1, "数据库文件信息更新失败");
                }
            }
        } else {
            qDebug() << "RollbackFileCommand: 数据库管理器未设置";
            // 只有在对象仍然有效时才发送信号
            if (isValid()) {
                emit rollbackFileCompleted(-1, "数据库管理器未设置");
            }
        }
    } else {
        qDebug() << "RollbackFileCommand: 获取文件信息失败:" << errmsg;
        // 只有在对象仍然有效时才发送信号
        if (isValid()) {
            emit rollbackFileCompleted(errcode, errmsg);
        }
    }
}

QString RollbackFileCommand::buildRequestUrl(const QString &baseUrl, const QString &fileId)
{
    return baseUrl + "/kms/api/kms/sync/files/" + fileId;
}

